﻿/*
    LoginModule.cs
    
    로그인 관련 메소드를 모두 모아놓은 클래스
 */

using System;
using System.IO;
using System.IO.IsolatedStorage;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using Microsoft.Phone.Shell;
using System.ComponentModel;

namespace TodayHumor
{
    public class LoginModule : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public enum State
        {
            NotLoggedIn, LoggingIn, LoggedIn
        }

        private State status = State.NotLoggedIn;
        public State Status
        {
            get { return status; }
            private set { status = value; NotifyPropertyChanged("Status"); }
        }

        /// <summary>
        /// 오늘의 유머에 로그인합니다.
        /// </summary>
        /// <param name="LoginId">로그인할 아이디입니다.</param>
        /// <param name="LoginPw">로그인할 비밀번호입니다.</param>
        /// <param name="AutoLogin">자동 로그인 여부입니다.</param>
        /// <returns>로그인이 성공했는지 실패했는지를 bool 형식으로 반환합니다.</returns>
        public async Task<bool> Login(string LoginId, string LoginPw, bool AutoLogin)
        {
            // 중복을 막기 위해서
            if (Status != State.NotLoggedIn) return false;

            Status = State.LoggingIn;

            // LoginId와 LoginPw 모두가 빈 값이 아니면 로그인을 진행한다.
            if (!String.IsNullOrEmpty(LoginId) && !String.IsNullOrEmpty(LoginPw))
            {
                RaonWebClient WebClient = new RaonWebClient();
                WebClient.Headers["Content-Type"] = "application/x-www-form-urlencoded";

                string LoginData = String.Format("id={0}&passwd={1}", HttpUtility.HtmlEncode(LoginId), HttpUtility.HtmlEncode(LoginPw));

                try
                {
                    // Login 정보가 담긴 string을 보내고
                    string LoginResult = await WebClient.UploadStringTaskAsync(new Uri("http://m.todayhumor.co.kr/member/login_end.php"), "POST", LoginData);

                    if (LoginResult.IndexOf("alert") == -1)
                    {
                        // 성공하면 Status를 바꾸고
                        Status = State.LoggedIn;

                        // 설정 정보에 자동 로그인 여부 / 아이디 / 비밀번호 정보를 저장한다.
                        Deployment.Current.Dispatcher.BeginInvoke(delegate
                        {
                            settings.AutoLogin = AutoLogin;
                            settings.LoginId = LoginId; settings.LoginPw = LoginPw;
                        });

                        return true;
                    }
                    else
                    {
                        // 아니면 로그인 실패 메시지를 보낸다.
                        Deployment.Current.Dispatcher.BeginInvoke(delegate
                        {
                            MessageBox.Show(new Regex("(?<=').*?(?=')").Match(LoginResult).Value, "로그인 실패", MessageBoxButton.OK);
                        });
                    }
                }
                catch
                {
                    Deployment.Current.Dispatcher.BeginInvoke(delegate
                    {
                        MessageBox.Show("현재 네트워크에 연결할 수 없습니다. 네트워크 상황을 확인하신 후 다시 시도해주세요.", "로그인 오류", MessageBoxButton.OK);
                    });
                }
            }
            else
            {
                // 둘 중 하나라도 빈 값이면 MessageBox를 띄운다.
                Deployment.Current.Dispatcher.BeginInvoke(delegate
                {
                    MessageBox.Show("아이디 혹은 비밀번호에 빈칸이 있습니다.", "로그인 오류", MessageBoxButton.OK);
                });

                Status = State.NotLoggedIn;
            }

            return false;
        }

        SettingsModule settings = new SettingsModule();

        /*
        string id, pw; 
        bool autoLogin;
        DependencyObject SysObj;

        public void Login(string LoginId, string LoginPw, bool AutoLogin, DependencyObject obj)
        {
            if (!String.IsNullOrEmpty(LoginId) && !String.IsNullOrEmpty(LoginPw))
            {
                try
                {
                    Deployment.Current.Dispatcher.BeginInvoke(delegate
                    {
                        CommonUtilities.GeneratePI(obj, "로그인하는 중입니다..");
                    });
                    id = LoginId; pw = LoginPw; autoLogin = AutoLogin; SysObj = obj;
                    HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://m.todayhumor.co.kr/member/login_end.php");

                    req.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; .NET CLR 2.0.50727; .NET CLR 3.0.04506.590; .NET CLR 3.5.20706; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)";
                    req.Method = "POST"; req.ContentType = "application/x-www-form-urlencoded";
                    
                    req.CookieContainer = App.Cookies;

                    req.BeginGetRequestStream(new AsyncCallback(LoginRequestCallback), req);
                }
                catch
                {
                    PushHandler(LoginFailed);
                }
            }
            else
            {
                Deployment.Current.Dispatcher.BeginInvoke(delegate
                {
                    MessageBox.Show("아이디 또는 비밀번호에 빈칸이 있습니다.");
                });
            }
        }

        void LoginRequestCallback(IAsyncResult result)
        {
            try
            {
                Deployment.Current.Dispatcher.BeginInvoke(delegate
                {
                    Encoding EucKrEncoding = new Korean.Text.Encoding.EuckrEncoding();

                    HttpWebRequest req = (HttpWebRequest)result.AsyncState;
                    Stream LoginStream = req.EndGetRequestStream(result);

                    string LoginData = String.Format("id={0}&passwd={1}", HttpUtility.HtmlEncode(id), HttpUtility.HtmlEncode(pw));
                    byte[] LoginDataArray = EucKrEncoding.GetBytes(LoginData);

                    LoginStream.Write(LoginDataArray, 0, LoginDataArray.Length);
                    LoginStream.Close();

                    req.BeginGetResponse(new AsyncCallback(LoginResultResponseCallback), req);
                });
            }
            catch
            {
                PushHandler(LoginFailed);
            }
        }

        void LoginResultResponseCallback(IAsyncResult result)
        {
            try
            {
                HttpWebRequest req = (HttpWebRequest)result.AsyncState;
                HttpWebResponse res = (HttpWebResponse)req.EndGetResponse(result);

                using (StreamReader ResultReader = new StreamReader(res.GetResponseStream(), new Korean.Text.Encoding.EuckrEncoding()))
                {
                    string ResultString = ResultReader.ReadToEnd();
                    if (ResultString.IndexOf("alert") == -1)
                    {
                        App.LoggedIn = true;

                        Deployment.Current.Dispatcher.BeginInvoke(delegate
                        {
                            settings.AutoLogin = autoLogin;
                            settings.LoginId = id; settings.LoginPw = pw;

                            PushHandler(LoginSuccessful);
                        });
                    }
                    else
                    {
                        Deployment.Current.Dispatcher.BeginInvoke(delegate
                        {
                            MessageBox.Show(new Regex("(?<=').*?(?=')").Match(ResultString).Value, "로그인 실패", MessageBoxButton.OK);
                        });
                    }
                }
            }
            catch
            {
                PushHandler(LoginFailed);
            }
        }
        */

        void NotifyPropertyChanged(string PropertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(PropertyName));
            }
        }
    }
}